import net.razorvine.pyro.NameServerProxy;
import net.razorvine.pyro.PyroProxy;

import java.io.IOException;

/**
 * I'm posting what I hope is useful for other newbies like me, which is an elaboration of the Pyro
 * simple example greeting.py appearing in http://pythonhosted.org//Pyro4/intro.html#with-a-name-server
 * but with a Java (rather than Python) client.
 * <p/>
 * That is, tying together the above with an elaboration of the "small code example in Java" that appears in:
 * https://pythonhosted.org/Pyro4/pyrolite.html
 * <p/>
 * FYI, I am running under Window 7 64-bit, WinPython-64bit-3.4.2.4 and Java1.6 (forced by my using ImageJ).
 * <p/>
 * Install Pyro4 onto Python side:
 * https://pythonhosted.org/Pyro4/install.html
 * <p/>
 * Install pyrolite on Java side (stick the .jar files wherever they need to be):
 * https://pythonhosted.org/Pyro4/pyrolite.html
 * <p/>
 * Under Python, start a Pyro NameServer: python -m Pyro4.naming
 * refs:
 * http://pythonhosted.org//Pyro4/intro.html#with-a-name-server
 * http://pythonhosted.org//Pyro4/nameserver.html#nameserver-nameserver
 * <p/>
 * Under Python, following http://pythonhosted.org//Pyro4/intro.html#with-a-name-server,
 * type in the contents of greeting.py to Python interpreter (omitting the print statement) or execute greeting.py.
 * What this does is to set up a "server"import java.io.IOException;
 * <p/>
 * class (i.e. something you want to serve up Python library methods
 * to Java client) and instantiate it, start the Pyro daemon, register the server class instance to the daemon and
 * also to the (auto-found) Pyro name server (already running due to previous step above).
 * <p/>
 * Under Java, essentially follow the "small code example in Java" that appears in
 * https://pythonhosted.org/Pyro4/pyrolite.html   but minding some clarification comments and possibly needed
 * adaptations, as I show below.  What this code does is to locate|grab the NameServerProxy, construct the
 * (java proxy|instance of the) Pyro-served Python server class instance (here, the class GreetingMaker),
 * invoke its method (get_fortune), and cast the return value to the appropriate Java type
 * (see Python-Java mappings in pyrolite readme.txt).
 * <p/>
 * <p/>
 * // Needed for pyrolite
 * import net.razorvine.pyro.*;
 * import java.io.*;   // Needed (?) for IOException thrown by some pyrolite methods
 */
public class testUnpickler {

    //    public void run(String arg) throws IOException {
//         The above "throws" augmentation would allow various exception-throwing pyrolite methods to
//          compile, but if class Greeting_Client were implementing some interface
//          e.g. "public class Greeting_Client implements ABC", it's likely the interface "ABC" 
//          couldn't be overridden with "throws IOException" .
//          So instead, we'd be required to use try-catch blocks below!
    public void run(String arg) {

        System.out.println("Here we go...");

        // NameServerProxy ns = NameServerProxy.locateNS(null);
        //  We have to break up the declaration and construction of the ns variable as follows, or
        //    declaring and constructing it in one line (as above) within the try block means ns
        //     is local (only) within that try block.
        //   We follow this idiom with further instances later below.
        NameServerProxy ns = null;  // needs to be initialized to null or get
        // "variable might not have been initialized" compilation error
        try {
            ns = NameServerProxy.locateNS(null);
        } catch (IOException e) {
            System.out.println("Caught LocateNS IOException: " + e.getMessage());
            return;
        }


        // PyroProxy remoteobject = new PyroProxy(ns.lookup("PYRONAME:example.greeting"));
        //   The Pyro dox for the Python side uses above argument form, but the Java-side Pyrolite uses
        //      below form without the PYRONAME: prefix.
        // PyroProxy remoteobject = new PyroProxy(ns.lookup("example.greeting"));
        PyroProxy remoteobject = null;
        try {
            remoteobject = new PyroProxy(ns.lookup("example.greeting"));
        } catch (IOException e) {
            System.out.println("Caught ns.lookup IOException: " + e.getMessage());
            ns.close();
            return;
        }

        // Object result = remoteobject.call("get_fortune", "Lucifer");
        Object result = null;
        try {
            result = remoteobject.call("get_fortune", "Lucifer");
        } catch (IOException e) {
            System.out.println("Caught remoteobject.call IOException: " + e.getMessage());
            ns.close();
            remoteobject.close();
            return;
        }

        String message = (String) result;  // cast to the type that 'get_fortune' returns
        System.out.println(message);
        remoteobject.close();
        ns.close();
    }

}